package uk.co.douglashoskins.weathercompare.ui;


import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import com.nokia.mid.ui.gestures.GestureEvent;
import com.nokia.mid.ui.gestures.GestureInteractiveZone;

import uk.co.douglashoskins.weathercompare.Assets;
import uk.co.douglashoskins.weathercompare.GestureAssist;
import uk.co.douglashoskins.weathercompare.Screen;
import uk.co.douglashoskins.weathercompare.WeatherCompare;
import uk.co.douglashoskins.weathercompare.controller.LocationToDisplay;
import uk.co.douglashoskins.weathercompare.controller.WeatherController;
import uk.co.douglashoskins.weathercompare.controller.WeatherObj;
import uk.co.douglashoskins.weathercompare.controller.WeatherObj.WeatherSummary;
import uk.co.douglashoskins.weathercompare.util.Weather;

public class MainScreen implements Screen {

	private WeatherController wc;
	private LocationToDisplay ltd;
	private boolean findingLocation = false;
	private int[] searchBounds = null, daySelectBounds = null, closeBounds = null;
	private int padding = 10;
	private boolean isToday = true;
	private double piBy2 = Math.PI / 2;
	private static final int GRIDS = 4;
	private WeatherObj[] weather = new WeatherObj[GRIDS];
	private boolean error[] = new boolean[GRIDS];
	private int boxWidth = 105;
	private int boxHeight = 80;
	private int avgHigh = 0, avgLow = 0;
	private boolean locationErr = false;
	private boolean netErr = false;
	
	public MainScreen() {
		wc = new WeatherController(this);
	}
	
	public void gotWeather(int i, WeatherObj wo) {
		weather[i] = wo;
	}
	
	public void weathErr(int i) {
		error[i] = true;
	}
	
	public void setToday(boolean isToday) {
		this.isToday = isToday;
	}
	
	public void setLocation(LocationToDisplay ltd) {
		findingLocation = false;
		this.ltd = ltd;
	}
	
	public void setFindingLocation(boolean searching) { this.findingLocation = searching; }
	
	private void processGesture(GestureEvent ge) {
		if (GestureAssist.isTapOrPress(ge)) {
			if (!findingLocation && searchBounds != null) {
				if (GestureAssist.tapWithinBounds(searchBounds, ge)) {
					wc.getLocation();
					locationErr = false;
					return;
				}
			} 
			if (daySelectBounds != null) {
				if (GestureAssist.tapWithinBounds(daySelectBounds, ge)) {
					if (isToday) { wc.swipeLeft(); }
					else { wc.swipeRight(); }
					return;
				}
			}
			if (closeBounds != null) {
				if (GestureAssist.tapWithinBounds(closeBounds, ge)) {
					WeatherCompare.m.notifyDestroyed();
				}
			}
		} else if (ge.getType() == GestureInteractiveZone.GESTURE_FLICK) {
			float dir = ge.getFlickDirection();
			if (dir > -piBy2 && dir < piBy2) {wc.swipeRight();}
			else { wc.swipeLeft();}
		}
	}
	public void gestureOccurred(GestureEvent ge) {
		processGesture(ge);
		WeatherCompare.c.repaint();
	}

	public void keyPressed(int keyCode, int gameAction) {
		
	}

	public void locationErr() {
		locationErr = true;
		WeatherCompare.c.repaint();
	}
	
	private void paintSearchBar(Graphics g) {
		g.setFont(WeatherCompare.LARGE);
		g.setColor(0x3EC0C7);
		g.fillRoundRect(padding, padding, WeatherCompare.width - 2*padding, Assets.SEARCH_GLOBE.getHeight() + 2 * padding, 5, 5);
		searchBounds = new int[] {padding, padding, WeatherCompare.width - 2*padding, Assets.SEARCH_GLOBE.getHeight() + 2 * padding};
		if (findingLocation) {
			g.setColor(0xBDA6A6);
		} else {
			g.setColor(0x3E57C7);
		}
		g.drawRoundRect(padding, padding, WeatherCompare.width - 2*padding, Assets.SEARCH_GLOBE.getHeight() + 2 * padding, 5, 5);
			
		g.setColor(0);
		int vertPadding = padding + ((Assets.SEARCH_GLOBE.getHeight() - WeatherCompare.LARGE.getHeight()) / 2);
		g.setClip(padding, padding + vertPadding, WeatherCompare.width - 3*padding - Assets.SEARCH_GLOBE.getWidth(), WeatherCompare.LARGE.getHeight());
		String str = "";
		if (netErr) {
			str = "Network error";
		} else if (locationErr) {
			str = "Location error";
		} else if (findingLocation) {
			str = "Finding location";
		} else if (ltd != null) {
			str = ltd.str;
		} else {
			str = "4Cast";
		}
		g.drawString(str, 2 * padding, padding + vertPadding, Graphics.TOP | Graphics.LEFT);
		g.setClip(0, 0, WeatherCompare.width, WeatherCompare.height);
		
		if (findingLocation) {
			g.drawImage(Assets.SEARCH_GLOBE_DISABLED, WeatherCompare.width - 2*padding, 2*padding, Graphics.RIGHT | Graphics.TOP);
		} else {
			g.drawImage(Assets.SEARCH_GLOBE, WeatherCompare.width - 2*padding, 2*padding, Graphics.RIGHT | Graphics.TOP);
		}
		
		String day = isToday ? "Today" : "Tomorrow";
		g.setFont(WeatherCompare.SMALL);
		int dayStrY = Assets.SEARCH_GLOBE.getHeight() + 3 * padding + (padding / 2);
		g.drawString(day, WeatherCompare.width / 2, dayStrY, Graphics.HCENTER | Graphics.TOP);
		if (isToday) {
			g.drawString(">", WeatherCompare.width - padding, dayStrY, Graphics.RIGHT | Graphics.TOP);
		} else {
			g.drawString("<", padding, dayStrY, Graphics.LEFT | Graphics.TOP);
		}
	}
	
	private void paintActualWeather(Graphics g, int i, int x, int y, WeatherSummary ws) {
		Image img = null;
		switch (ws.code) {
			case Weather.CLOUD: case Weather.FOG: img = Assets.CLOUD; break;
			case Weather.RAIN: img = Assets.RAIN; break;
			case Weather.SNOW: img = Assets.SNOW; break;
			case Weather.SUN: img = Assets.SUN; break;
			case Weather.SUNNY_INTERVALS: img = Assets.SUNNY_INTERVALS; break;
			case Weather.THUNDERSTORM: img = Assets.THUNDERSTORM; break;
			default: img = Assets.CLOUD;
		}
		g.drawImage(img, x + 2, y + boxHeight / 2, Graphics.LEFT | Graphics.VCENTER);
		g.setFont(WeatherCompare.LARGE);
		g.setColor(0xFA3953);
		g.drawString(ws.high + "\u00b0C", x + boxWidth - 2, y + 2, Graphics.TOP | Graphics.RIGHT);
		g.setColor(0x2485ED);
		g.drawString(ws.low + "\u00b0C", x + boxWidth - 2, y + boxHeight - 2, Graphics.BOTTOM | Graphics.RIGHT);
	}
	
	private void paintWeatherGrid(Graphics g, int i, int top) {
		WeatherObj wo = weather[i];
		if (error[i]) {
			g.setColor(0xff0000);
		} else if (wo == null) {
			g.setColor(0xBDA6A6);
		} else {
			g.setColor(0x3E57C7);
		}
		int x = 0, y = 0;
		if (i == 0 || i == 2) {
			x = padding;
		} else {
			x = 2 * padding + boxWidth;
		}
		
		if (i == 0 || i == 1) {
			y = top;
		} else {
			y = top + boxHeight + padding;
		}
		g.drawRoundRect(x, y, boxWidth, boxHeight, 5, 5);
		if (error[i]) {
			g.setFont(WeatherCompare.LARGE);
			g.drawString("error", x + boxWidth / 2, y + boxHeight / 2, Graphics.HCENTER | Graphics.TOP);
		} else if (wo == null) {
			g.drawImage(Assets.SEARCH_DB, x + boxWidth / 2, y + boxHeight / 2, Graphics.HCENTER | Graphics.VCENTER);
		} else {
			g.drawImage(wo.logo, x, y + boxHeight, Graphics.BOTTOM | Graphics.LEFT);
			paintActualWeather(g, i, x, y, isToday ? wo.today : wo.tomorrow);
		}
	}
	
	public void setAverages(int avgHigh, int avgLow) {
		this.avgHigh = avgHigh;
		this.avgLow = avgLow;
	}
	
	private void paintWeatherGrid(Graphics g) {
		int top = 4 * padding + Assets.SEARCH_GLOBE.getHeight() + WeatherCompare.SMALL.getHeight();
		for (int i=0; i< GRIDS; i++) {
			paintWeatherGrid(g, i, top);
		}
	}
	
	private void fillCircle(Graphics g, int centerX, int centerY, int diam) {
		int radius = diam / 2;
		g.fillArc(centerX - radius, centerY - radius, diam, diam, 0, 360);
	}
	
	private void paintAvg(Graphics g) {
		String s = "Avg high: " + avgHigh + "\u00b0C, avg low: " + avgLow + "\u00b0C";
		g.setColor(0xffffff);
		g.setFont(WeatherCompare.SMALL);
		g.drawString(s, WeatherCompare.width / 2, 280, Graphics.HCENTER | Graphics.BOTTOM);
	}
	
	private void paintTouchButtons(Graphics g) {
		g.setColor(0xE6E34E);
		if (isToday) {
			fillCircle(g, 100, 300, 16);
			fillCircle(g, 140, 300, 10);
		} else {
			fillCircle(g, 100, 300, 10);
			fillCircle(g, 140, 300, 16);
		}
		daySelectBounds = new int[] {95, 280, 50, 40};
	}
	
	public void paint(Graphics g) {
		if (!Assets.READY) {
			return;
		}
		g.drawImage(Assets.VATERSAY, 0, 0, Graphics.TOP | Graphics.LEFT);
		paintSearchBar(g);
		paintWeatherGrid(g);
		paintAvg(g);
		paintTouchButtons(g);
		g.setFont(WeatherCompare.LARGE);
		g.setColor(0xff0000);
		g.drawString("X", WeatherCompare.width, WeatherCompare.height, Graphics.RIGHT | Graphics.BOTTOM);
		closeBounds = new int[] {220, 300, 20, 20};
	}
}
